﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing.Design;
using System.ComponentModel.Design.Serialization;
using System.CodeDom;
using ProgNetComponentsDx.Browsers.Design.Editors;
using ProgNetComponents.Design.Attributes;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;
using System.Windows.Forms;
using DevExpress.XtraEditors.Controls;
using ProgNetComponentsDx.Base.Classes;
using ProgNetComponentsDx.Browsers.Design;
using ProgNetComponentsDx.Controls.Editors;
using System.Data;

namespace ProgNetComponentsDx.Browsers
{
    public class BrowserSettings : BaseSettings
    {
        #region Is Borwsable methods
        private bool IsAddBrowserDialogButtonBrowsable()
        {
            return BrowserId.IsNotNull() && DisplayType != BrowserSettingsDisplayType.DialogWindow;
        }
        private bool IsAllowNewRecordsBrowsable()
        {
            return BrowserId.IsNotNull() &&
                (Owner is LookUpEdit ||
                 Owner is RepositoryItemGridLookUpEdit ||
                 Owner is GridLookUpEdit ||
                 Owner is RepositoryItemGridLookUpEdit);
        }
        #endregion
        public BrowserSettings(object target, IExtenderProvider provider)
            : base(target, provider)
        {
            AdditionalBrowserPopupKey = Keys.F2;
            BrowserDialogPopupKey = Keys.F3;
            AdditionalButton = ButtonPredefines.Plus;
            BrowserDialogButtonType = ButtonPredefines.Ellipsis;
        }

        private object _BrowserId;
        private string _DisplayFilter;
        private string _AdditionalBrowserDisplayFilter;
        private BrowserSettingsDisplayType _DisplayType;
        private bool _AllowNewRecords;
        internal bool ShouldClearData
        {
            get;
            set;
        }
        private object _AdditionalBrowserId;

        #region Browser
        [Editor(typeof(BrowserNameEditor), typeof(UITypeEditor)), BrowsableByPropertyValueType("Owner", typeof(RepositoryItemLookUpEdit), typeof(RepositoryItemGridLookUpEdit), typeof(LookUpEdit), typeof(GridLookUpEdit), typeof(RepositoryItemMultiSelectGridEdit), typeof(MultiSelectGridEdit)), RefreshProperties(RefreshProperties.All)]
        [TypeConverter(typeof(ProgNetComponents.Design.TypeConverters.BaseConstTypeConverter)), System.ComponentModel.NotifyParentProperty(true), AlwaysSerialize]
        public object BrowserId
        {
            get { return _BrowserId; }
            set
            {
                if (_BrowserId != value)
                {
                    _BrowserId = value;
                    OnSettingsChanged();
                    ShouldClearData = value.IsNotNull();
                }
            }
        }

        [HiddenByPropertyValue("BrowserId", "", null)]
        [System.ComponentModel.NotifyParentProperty(true)]
        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        public BrowserSettingsDisplayType DisplayType
        {
            get
            {
                if (Owner is RepositoryItemMultiSelectGridEdit)
                    return BrowserSettingsDisplayType.DropDown;
                return _DisplayType;
            }
            set
            {
                if (MultiSelect && value != BrowserSettingsDisplayType.DialogWindow)
                    return;
                this.SetFieldValue(ref _DisplayType, value);
            }
        }

        [HiddenByPropertyValue("BrowserId", "", null)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public string DisplayFilter
        {
            get { return _DisplayFilter; }
            set
            {
                this.SetFieldValue(ref _DisplayFilter, value);
            }
        }

        [BrowsableByMethod("IsAllowNewRecordsBrowsable")]
        [System.ComponentModel.NotifyParentProperty(true)]
        public bool AllowNewRecords
        {
            get { return _AllowNewRecords; }
            set
            {
                _AllowNewRecords = value;
                OnSettingsChanged();
            }
        }

        [Browsable(false)]
        [DefaultValue(null)]
        public Browser Browser
        {
            get;
            set;
        }

        [System.ComponentModel.NotifyParentProperty(true)]
        [BrowsableByMethod("IsAddBrowserDialogButtonBrowsable")]
        public bool AddBrowserDialogButton
        {
            get;
            set;
        }

        [HiddenByPropertyValue("AddBrowserDialogButton", false)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public Keys BrowserDialogPopupKey
        {
            get;
            set;
        }

        [System.ComponentModel.NotifyParentProperty(true)]
        [BrowsableByPropertyValue("AddBrowserDialogButton", true)]
        public ButtonPredefines BrowserDialogButtonType
        {
            get;
            set;
        }

        private bool _MultiSelect;

        [HiddenByPropertyValue("BrowserId", "", null)]
        [System.ComponentModel.NotifyParentProperty(true)]
        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        public bool MultiSelect
        {
            get { return _MultiSelect; }
            set
            {
                this.SetFieldValue(ref _MultiSelect, value);
                if (value)
                    this.DisplayType = BrowserSettingsDisplayType.DialogWindow;
            }
        }

        private string _MultiSelectSeparator = ", ";

        [HiddenByPropertyValue("MultiSelect", false)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public string MultiSelectSeparator
        {
            get { return _MultiSelectSeparator; }
            set { _MultiSelectSeparator = value; }
        }
            
        #endregion


        #region Additional Browser

        [Editor(typeof(BrowserNameEditor), typeof(UITypeEditor))]
        [BrowsableByPropertyValueType("Owner", typeof(RepositoryItemTextEdit), typeof(TextEdit))]
        [RefreshProperties(RefreshProperties.All)]
        [System.ComponentModel.NotifyParentProperty(true)]
        [DefaultValue(null)]
        public object AdditionalBrowserId
        {
            get { return _AdditionalBrowserId; }
            set
            {
                if (_AdditionalBrowserId != value)
                {
                    _AdditionalBrowserId = value;
                    OnSettingsChanged();
                }
            }
        }

        [System.ComponentModel.NotifyParentProperty(true)]
        [HiddenByPropertyValue("AdditionalBrowserId", "", null)]
        [DefaultValue(ButtonPredefines.Plus)]
        public ButtonPredefines AdditionalButton
        {
            get;
            set;
        }

        [HiddenByPropertyValueAttribute("AdditionalBrowserId", "", null)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public BrowserSettingsDisplayType AdditionalBrowserDisplayType
        {
            get;
            set;
        }

        [HiddenByPropertyValue("AdditionalBrowserId", "", null)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public Keys AdditionalBrowserPopupKey
        {
            get;
            set;
        }

        [HiddenByPropertyValue("AdditionalBrowserId", "", null)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public string AdditionalBrowserDisplayFilter
        {
            get { return _AdditionalBrowserDisplayFilter; }
            set
            {
                if (value != _AdditionalBrowserDisplayFilter)
                {
                    _AdditionalBrowserDisplayFilter = value;
                    OnSettingsChanged();
                }
            }
        }

        [HiddenByPropertyValue("AdditionalBrowserId", "", null)]
        [System.ComponentModel.NotifyParentProperty(true)]
        public bool UseExistingButton
        {
            get;
            set;
        }

        [Browsable(false)]
        [DefaultValue(null)]
        public Browser AdditionalBrowser
        {
            get;
            set;
        }

        [Browsable(false)]
        [DefaultValue(null)]
        public LookUpEdit AdditionalBrowserLookupEdit
        {
            get;
            set;
        }
        #endregion

        public event EventHandler AdditionalBrowserValueChanged;
        public event ChangingEventHandler AdditionalBrowserValueChanging;
        public event CreateNewRowHandler CreateNewRow;

        internal void OnAdditionalBrowserValueChanged(object sender)
        {
            if (AdditionalBrowserValueChanged != null)
                AdditionalBrowserValueChanged(sender, EventArgs.Empty);
        }
        internal void OnAdditionalBrowserValueChanging(object sender, ChangingEventArgs e)
        {
            if (AdditionalBrowserValueChanging != null)
                AdditionalBrowserValueChanging(sender, e);
        }
        internal void OnCreateNewRow(DataRow row, string newValue)
        {
            if (CreateNewRow != null)
            {
                CreateNewRowEventArgs e = new CreateNewRowEventArgs(row, newValue);
                CreateNewRow(Owner, e);
            }
        }
    }

    public enum BrowserSettingsDisplayType
    {
        Default,
        ComboDropDown,
        DropDown,
        DialogWindow,
        ConfigSpecified
    }

    public class CreateNewRowEventArgs : EventArgs
    {
        public CreateNewRowEventArgs(DataRow row, string displayValue)
        {
            this.NewRow = row;
            this.DisplayValue = displayValue;
        }

        public DataRow NewRow
        {
            get;
            private set;
        }
        public string DisplayValue
        {
            get;
            private set;
        }
    }

    public delegate void CreateNewRowHandler(object sender, CreateNewRowEventArgs e);
}
